package com.zmn.oms.dubbo.impl.normal.order;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.oms.business.interfaces.apply.CancelApplyBService;
import com.zmn.oms.business.interfaces.orderamount.OrderAmountCalcBService;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.business.interfaces.work.OrderWorkAmountBService;
import com.zmn.oms.common.constant.OmsErrorCodeConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.constant.TriggerAmountChangeEnum;
import com.zmn.oms.common.dio.normal.order.*;
import com.zmn.oms.common.enums.OrderWorkCancelEntranceEnum;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.dubbo.interfaces.normal.order.NormalOrderWorkModifyRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.bo.orderamount.OrderAmountCalcBO;
import com.zmn.oms.model.bo.orderamount.ReCalcOrderAmountDIO;
import com.zmn.oms.model.bo.work.apply.cancel.CancelApplyResultBO;
import com.zmn.oms.model.dto.order.NonClaimOrderDTO;
import com.zmn.oms.model.dto.remark.OrderRemarkDetailDTO;
import com.zmn.oms.model.dto.work.modify.CheckOrderServItemTypeDTO;
import com.zmn.oms.model.dto.work.modify.must.CancelApplyDTO;
import com.zmn.oms.model.dto.work.modify.must.ZsCancelDTO;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.work.OperatePermissionVO;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.order.ZsOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkOperatePermissionBService;
import com.zmn.oms.zmn.normal.business.interfaces.work.ZsNormalWorkBService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Objects;

/**
 * 类描述：
 *
 * @author wangxiaokun
 * @since 2021/04/14 18:02
 */
@Slf4j
@Service(loadbalance = "roundrobin", timeout = 20000, retries = 2, version = DubboConsts.INTERFACE_VERSION, validation = "true")
public class NormalOrderWorkModifyRemoteServiceImpl implements NormalOrderWorkModifyRemoteService {

    static final String TAG = "啄木鸟-普通单";

    @Autowired
    protected ZsNormalWorkBService zsNormalWorkBService;
    @Autowired
    protected ZsOrderBService zsOrderBService;
    @Autowired
    protected OrderWorkService orderWorkService;
    @Autowired
    protected OrderAmountCalcBService orderAmountCalcBService;
    @Autowired
    protected OrderWorkAmountBService orderWorkAmountBService;
    @Autowired
    private ServItemBService servItemBService;
    @Autowired
    private ZsOrderWorkOperatePermissionBService zsOrderWorkOperatePermissionBService;
    @Autowired
    private CancelApplyBService cancelApplyBService;

    @Override
    public ResponseDTO cancelOrder(CancelOrderDIO cancelOrderDIO) {
        log.info("[{}] 取消订单：{}", TAG, cancelOrderDIO);

        try {
            ZsCancelDTO zsCancelDTO = new ZsCancelDTO();
            zsCancelDTO.setOrderId(cancelOrderDIO.getOrderId());
            zsCancelDTO.setWorkId(cancelOrderDIO.getWorkId());
            zsCancelDTO.setContent(cancelOrderDIO.getRemark());
            if (Objects.nonNull(cancelOrderDIO.getReasonMap()) && cancelOrderDIO.getReasonMap().size() > 0) {
                List<OrderRemarkDetailDTO> detailDTOList = Lists.newArrayList();
                cancelOrderDIO.getReasonMap().forEach((k,v) -> {
                    OrderRemarkDetailDTO dto = new OrderRemarkDetailDTO() ;
                    dto.setMapId(k);
                    dto.setMapName(v);
                    detailDTOList.add(dto);
                });
                zsCancelDTO.setDetailDTOList(detailDTOList);
            }
            // 操作人信息
            zsCancelDTO.setOperator(cancelOrderDIO.getOperator());
            zsCancelDTO.setOperatorId(cancelOrderDIO.getOperatorId());
            zsCancelDTO.setOperatorType(cancelOrderDIO.getOperatorType());
            zsCancelDTO.setEntranceId(cancelOrderDIO.getEntranceId());
            if (Objects.equals(OrderWorkCancelEntranceEnum.SMS.getCode(), zsCancelDTO.getEntranceId())) {
                zsCancelDTO.setOperatorLogRemark("用户短信取消");
            }
            zsNormalWorkBService.saveCancel(zsCancelDTO);
            return ResponseDTO.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseDTO.fail(e.getMessage());
        }
    }

    @Override
    @Deprecated
    public ResponseDTO cancelOrderApply(@NotNull(message = "入参不能为空") CancelOrderApplyDIO cancelOrderApplyDIO) {
        log.info("[{}] 取消申请订单：{}", TAG, cancelOrderApplyDIO);
        if (cancelOrderApplyDIO.getReasonMap() == null || cancelOrderApplyDIO.getReasonMap().isEmpty()) {
            return ResponseDTO.fail(OmsErrorCodeConsts.PARAMS_VERIFY_EXCEPTION, "取消缘由不能为空！");
        }
        try {
            CancelApplyDTO cancelApplyDTO = new CancelApplyDTO();
            cancelApplyDTO.setOrderId(cancelOrderApplyDIO.getOrderId());
            cancelApplyDTO.setWorkId(cancelOrderApplyDIO.getWorkId());
            cancelApplyDTO.setContent(cancelOrderApplyDIO.getRemark());
            cancelApplyDTO.setReasonIdList(cancelOrderApplyDIO.getReasonIdList());
            List<OrderRemarkDetailDTO> detailDTOList = Lists.newArrayList();
            cancelOrderApplyDIO.getReasonMap().forEach((k,v) -> {
                OrderRemarkDetailDTO dto = new OrderRemarkDetailDTO() ;
                dto.setMapId(k);
                dto.setMapName(v);
                detailDTOList.add(dto);
            });
            cancelApplyDTO.setDetailDTOList(detailDTOList);

            // 操作人信息
            cancelApplyDTO.setOperator(cancelOrderApplyDIO.getOperator());
            cancelApplyDTO.setOperatorId(cancelOrderApplyDIO.getOperatorId());
            cancelApplyDTO.setOperatorType(cancelOrderApplyDIO.getOperatorType());
            cancelApplyDTO.setEntranceId(cancelOrderApplyDIO.getEntranceId());
            zsNormalWorkBService.saveCancelApply(cancelApplyDTO);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseDTO.fail(OmsErrorCodeConsts.SYS_ERROR, e.getMessage());
        }

        return ResponseDTO.success();
    }

    @Override
    public ResponseDTO claimOrderWork(Long orderId, Long userId) {
        log.info("认领订单入参：orderId[{}]", orderId);

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        if (Objects.isNull(orderWork)) {
            return ResponseDTO.fail("订单不存在");
        }

        if (!Objects.equals(orderWork.getResultStatus(),OrderStatusConsts.WORK_RESULT_DOING)
                || orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_COMPLETE) {
            return ResponseDTO.success();
        }
        if (Objects.equals(orderWork.getMasterPayStatus(), PayConsts.PAY_STATUS_DONE)) {
            return ResponseDTO.success();
        }

        ReCalcOrderAmountDIO calcOrderAmountDIO = orderAmountCalcBService.getReCalcOrderAmountDIO(orderWork);
        OrderAmountCalcBO orderAmountCalcBO;
        try {
            orderAmountCalcBO = orderAmountCalcBService.reCalcOrderAmountAndDiscountAmount(TriggerAmountChangeEnum.CLAIM_ORDER, calcOrderAmountDIO, null);
            orderWorkAmountBService.updateAmountAndDiscount(orderAmountCalcBO, orderWork);
            return ResponseDTO.success();
        } catch (OmsBaseException e) {
            log.error(e.getMessage(), e);
            return ResponseDTO.fail(e.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseDTO.fail("认领-获取优惠异常");
        }
    }


    @Override
    public ResponseDTO nonClaimOrderWork(@NotNull(message = "入参不能为空") NonClaimOrderDIO nonClaimOrderDIO) {
        log.info("用户不认领订单入参：[{}]", JSON.toJSONString(nonClaimOrderDIO));
        try {
            NonClaimOrderDTO dto = new NonClaimOrderDTO();
            dto.setOrderId(nonClaimOrderDIO.getOrderId());
            dto.setWorkId(nonClaimOrderDIO.getOrderId());
            dto.setUserId(nonClaimOrderDIO.getUserId());
            dto.setTelephone(nonClaimOrderDIO.getPhone());
            dto.setOperator(nonClaimOrderDIO.getOperator());
            dto.setOperatorId(nonClaimOrderDIO.getOperatorId());
            dto.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_USER);
            zsOrderBService.insertNonClaimOrder(dto);
            return ResponseDTO.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseDTO.fail(e.getMessage());
        }

    }

    @Override
    public ResponseDTO checkOrderWorkServItemType(CheckOrderServItemTypeDIO checkOrderServItemTypeDIO) {
        log.info("NormalOrderWorkModifyRemoteServiceImpl.checkOrderWorkServItemType checkOrderServItemTypeDIO={}", checkOrderServItemTypeDIO);
        CheckOrderServItemTypeDTO dto = new CheckOrderServItemTypeDTO();
        dto.setOrderId(checkOrderServItemTypeDIO.getOrderId());
        dto.setWorkId(checkOrderServItemTypeDIO.getWorkId());
        dto.setServItemType(checkOrderServItemTypeDIO.getServItemType());
        try {
            servItemBService.checkOrderWorkServItemType(dto);
        } catch (Exception e) {
            log.error("checkOrderWorkServItemType error={}", e);
            return ResponseDTO.fail(e.getMessage());
        }
        return ResponseDTO.success();
    }

    @Override
    public ResponseDTO checkOrderWorkCancel(CheckOrderCancelDIO checkOrderCancelDIO) {
        log.info("检查工单取消 dio={}", checkOrderCancelDIO);
        try {
            // 校验 取消申请
            if (!Objects.equals(checkOrderCancelDIO.getEntranceId(), OrderWorkCancelEntranceEnum.CANCEL_APPLY.getCode())) {
                // 有待审核的取消申请不允许取消
                CancelApplyResultBO waitCancelInfo = cancelApplyBService.getWaitCancelInfo(checkOrderCancelDIO.getOrderId(), checkOrderCancelDIO.getWorkId());
                if (Objects.equals(waitCancelInfo.getUserWaitCancelStatus(), GlobalConsts.YES) || Objects.equals(waitCancelInfo.getMasterWaitCancelStatus(), GlobalConsts.YES)) {
                    return ResponseDTO.fail("存在待审核的取消申请，请先审核后再试！");
                }
            }
            OperatePermissionVO operatePermission = zsOrderWorkOperatePermissionBService.getOperatePermission(checkOrderCancelDIO.getOrderId(), checkOrderCancelDIO.getWorkId(), OrderConsts.ORDER_OP_TYPE_CANCEL, checkOrderCancelDIO.getOperatorType());
            if (!operatePermission.getCanOperate()) {
                return ResponseDTO.fail(operatePermission.getMsg());
            }
        } catch (Exception e) {
            return ResponseDTO.fail(e.getMessage());
        }
        return ResponseDTO.success();
    }
}
